﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Collections;
using System.Collections.ObjectModel;
using System.Xml;
using System.Xml.XPath;

using log4net;

namespace ConfigUtilLib
{
    public class GeneralConfig
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        public const string kickoffIntervalName = "kickoffInterval";
        public const string debugPortName = "debugPort";
        public long kickoffInterval;
        public long backdoorPort;

        /// <summary>
        ///    Reading Configuration General Configuration
        /// </summary>
        /// <param name="configNode"></param>
        /// <returns></returns>
        public bool  LoadConfiguration(XmlNode configNode)
        {
            bool retVal = true;

            log.DebugFormat("Started Reading General Configuration Section..");
            XmlNode kickOffIntrlNode = configNode.SelectSingleNode(kickoffIntervalName);
            XmlNode backdoorPortNode = configNode.SelectSingleNode(debugPortName);

            if( kickOffIntrlNode == null   )
            {
                Console.Error.WriteLine(" kickOffInterval : Missing ..");
                retVal = false;
            }

            if (backdoorPortNode != null)
            {
                backdoorPort = System.Convert.ToInt64(backdoorPortNode.Value);             
            }
            else
            {
                Console.Error.WriteLine(" Backdoor port  : Missing ..");
            }

            kickoffInterval = System.Convert.ToInt64(kickOffIntrlNode.Value);
            backdoorPort = System.Convert.ToInt64(backdoorPortNode.Value);

            log.DebugFormat("Completed Reading General Configuration Section..");
            return retVal;
        }
    }

    /// <summary>
    /// Application Configuration Object.
    /// </summary>
    public class AppConfig
    {
        private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
        private  List<FetcherRecord> _fetcherRecords { get;  set; }
        public   GeneralConfig appgeneralConfig { get; private set; }

        private  const string AppGeneralConfigName = "//AppGeneralConfig";
        private const string FetcherRecordConfigName = "//FetcherRecord";

        public ReadOnlyCollection<FetcherRecord>  FetcherRecords
        { 
              get 
                 {   ReadOnlyCollection<FetcherRecord> readOnlyCollection = new ReadOnlyCollection<FetcherRecord>(_fetcherRecords);
                     return readOnlyCollection;
                }
         }
        

        public AppConfig()
        {
            _fetcherRecords = new List<FetcherRecord>();
            appgeneralConfig = new GeneralConfig();
        }


        public static AppConfig readConfiguration(string configFilePath)
        {
            AppConfig _appConfig = null;            
            XmlDocument xmlConfigDoc = new XmlDocument();

            try
            {
                xmlConfigDoc.Load(configFilePath);
                _appConfig = new AppConfig();

                if (!_appConfig.readConfiguration(xmlConfigDoc))
                {
                    log.DebugFormat("Configuration reading Failed :  " + configFilePath);
                    return null;
                }

            }
            catch (Exception e)
            {
                // Logging Error 
                Console.Error.WriteLine(" Exception while reading Config File " + configFilePath);
            }

            return _appConfig;
        }

        public  bool  readConfiguration(XmlDocument xmlConfigDoc)
        {
            //1. Read App Specific Config 
            XmlNode generalConfigNode = xmlConfigDoc.SelectSingleNode(AppGeneralConfigName);
            if (!appgeneralConfig.LoadConfiguration(generalConfigNode))
            {
                log.DebugFormat(" Failed to Load General Configuration Section ");
                return false;
            }

            //2. Read Fetcher Records
            XmlNodeList fetcherList = xmlConfigDoc.SelectNodes(FetcherRecordConfigName);
            log.DebugFormat(" Number of Fetcher Records to read : " + fetcherList.Count);

            foreach (XmlNode fetcherNode in fetcherList)
            {
                FetcherRecord fetcherRec = new FetcherRecord();
                if (!fetcherRec.LoadConfiguration(fetcherNode))
                {
                    log.DebugFormat(" Failed to read Fetcher record");
                    return false;
                }

                if (fetcherRec.isActive)
                {
                    _fetcherRecords.Add(fetcherRec);
                }
            }
            
            return true;
        }
     


    }
}
